package cate.game.activity.goldegg;

import cate.common.table.activity.goldegg.row.GoldEggBaseRow;
import cate.common.table.activity.goldegg.row.GoldEggDrawRewardRow;
import cate.common.table.activity.goldegg.row.GoldEggRewardPoolRow;
import cate.common.table.d.GDOperation;
import cate.common.util.GameResult;
import cate.common.util.random.RWList;
import cate.game.activity.base.core.RoleActivitySingle;
import cate.game.activity.goldegg.msg.BreakResultResp;
import cate.game.activity.goldegg.msg.GoldEggActivityInfoResp;
import cate.game.res.MixRes;
import cate.game.res.MixResItem;
import cate.game.role.Role;
import easy.java.dev.note.NoteField;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class GoldEggActivity extends RoleActivitySingle {
    @NoteField("保底抽奖次数")
    public int drawTimes;
    @NoteField("历史抽奖次数")
    public int historyDrawTimes;
    @NoteField("领奖记录")
    public Map<Integer, Boolean> recordMap;
    @NoteField("免费抽奖次数")
    public int freeTimes;
    @NoteField("钻石抽奖次数")
    public int m1DrawTimes;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (recordMap == null) {
            recordMap = new HashMap<>();
        }
    }

    @Override
    public void onDaySpan(boolean silence) {
        super.onDaySpan(silence);
        this.freeTimes = 0;
        this.m1DrawTimes = 0;
        if (!silence && enable()) {
            noticeUpdate();
        }
    }

    public GameResult<GoldEggActivity> draw(int type) {
        GameResult<GoldEggActivity> r = new GameResult<>();
        GoldEggBaseRow baseRow = findBaseRow();
        if (baseRow == null) {
            return r.fail("活动配置不存在");
        }
        if (type == baseRow.FREE_CALL) {
            if (freeTimes >= baseRow.freeLimit) {
                return r.fail("今日免费次数已用尽");
            }
            freeTimes++;
        } else if (type == baseRow.M1_CALL) {
            if (StringUtils.isBlank(baseRow.m1Cost)) {
                return r.fail("未配置钻石消耗");
            }
            if (baseRow.m1Limit > 0 && m1DrawTimes + 1 > baseRow.m1Limit) {
                return r.fail("钻石砸蛋次数不足");
            }
            MixRes cost = new MixRes(baseRow.m1Cost);
            GameResult<MixResItem> consume = cost.consume(role);
            if (!consume.ok()) {
                return r.fail(consume);
            }
        } else {
            if (StringUtils.isBlank(baseRow.oneCost)) {
                return r.fail("消耗未配置");
            }
            MixRes cost = new MixRes(baseRow.oneCost);
            GameResult<MixResItem> consume = cost.consume(role);
            if (!consume.ok()) {
                return r.fail(consume);
            }
        }
        BreakResultResp resp = new BreakResultResp();
        resp.reward = new MixRes();
        if (type == baseRow.M1_CALL) {
            MixRes exp = new MixRes(baseRow.exp);
            GameResult<Void> addExp = exp.add(role, true);
            if (!addExp.ok()) {
                return r.fail(addExp);
            }
            resp.reward.addList(exp.copy());
        }
//        消耗完开始抽奖
        r = drawSomeTimes(1, resp);
        if (type == baseRow.M1_CALL) {
            m1DrawTimes++;
        }
        r.data = this;
        return r;
    }

    public GameResult<GoldEggActivity> tenDraw(int type) {
        GameResult<GoldEggActivity> r = new GameResult<>();
        GoldEggBaseRow baseRow = findBaseRow();
        if (baseRow == null) {
            return r.fail("活动配置不存在");
        }
        if (type == baseRow.M1_CALL) {
            if (StringUtils.isBlank(baseRow.m1Cost)) {
                return r.fail("未配置钻石消耗");
            }
            if (baseRow.m1Limit > 0 && m1DrawTimes + 10 > baseRow.m1Limit) {
                return r.fail("钻石砸蛋次数不足");
            }
            MixRes cost = new MixRes(baseRow.m1Cost).multiply(10);
            GameResult<MixResItem> consume = cost.consume(role);
            if (!consume.ok()) {
                return r.fail(consume);
            }
        } else {
            if ((StringUtils.isBlank(baseRow.tenCost))) {
                return r.fail("消耗未配置");
            }
            MixRes cost = new MixRes(baseRow.tenCost);
            GameResult<MixResItem> consume = cost.consume(role);
            if (!consume.ok()) {
                return r.fail(consume);
            }
        }
        BreakResultResp resp = new BreakResultResp();
        resp.reward = new MixRes();
        if (type == baseRow.M1_CALL) {
            MixRes exp = new MixRes(baseRow.exp).multiply(10);
            GameResult<Void> addExp = exp.add(role, true);
            if (!addExp.ok()) {
                return r.fail(addExp);
            }
            resp.reward.addList(exp.copy());
        }
//        消耗完开始抽奖
        r = drawSomeTimes(10, resp);
        if (type == baseRow.M1_CALL) {
            m1DrawTimes += 10;
        }
        r.data = this;
        return r;
    }

    private GameResult<GoldEggActivity> drawSomeTimes(int times, BreakResultResp resp) {
        GameResult<GoldEggActivity> r = new GameResult<>();
        GoldEggBaseRow baseRow = findBaseRow();
        MixRes reward = new MixRes();
        List<Integer> result = new ArrayList<>();
        for (int i = 0; i < times; i++) {
            GoldEggRewardPoolRow row;
            if (drawTimes >= baseRow.cheatTimes) {
                row = drawExe(baseRow.cheatGroup);
                reward.addList(new MixRes(row.reward));
                drawTimes = 0;
            } else {
                row = drawExe(baseRow.normalGroup);
                reward.addList(new MixRes(row.reward));
                drawTimes++;
            }
            result.add(row.id);
            historyDrawTimes++;
        }
        reward.add(role, true, GDOperation.GOLD_EGG);
        resp.rewards = result;
        role.sendNow(resp);
        role.getHistory().action.drawGoldEgg(times);
        return r;
    }

    public GameResult<GoldEggActivity> takeTimesReward(int tid) {
        GameResult<GoldEggActivity> r = new GameResult<>();
        r.data = this;
        GoldEggBaseRow baseRow = findBaseRow();
        if (baseRow == null) {
            return r.fail("活动配置不存在");
        }
        GoldEggDrawRewardRow row = findDrawRewardRow(tid);
        if (row == null) {
            return r.fail("奖励配置不存在");
        }
        if (recordMap.containsKey(tid) && recordMap.get(tid)) {
            return r.fail("奖励已领取");
        }
        if (historyDrawTimes < row.times) {
            return r.fail("抽奖次数不足");
        }
        MixRes res = new MixRes(row.reward);
        res.addAndDialog(role, true, GDOperation.GOLD_EGG, tid);
        recordMap.put(tid, true);
        refresh();
        return r;
    }

    public void refresh() {
        GoldEggBaseRow baseRow = findBaseRow();
        List<Integer> ids = findDrawRewardRows(baseRow.timesGroup).stream().map(row -> row.id).collect(Collectors.toList());
        if (recordMap.keySet().containsAll(ids)) {
            int maxTimes = role.getGame().table.goldEgg.times.findMaxTimes(baseRow.timesGroup);
            if (maxTimes == 0) {
                return;
            }
            this.historyDrawTimes -= maxTimes;
            this.recordMap.clear();
        }
    }


    @Override
    public void onEnter() {
        super.onEnter();
        if (!enable()) {
            return;
        }
        refresh();
    }

    private GoldEggRewardPoolRow drawExe(int group) {
        List<GoldEggRewardPoolRow> poolList = findPoolList(group);
        RWList<GoldEggRewardPoolRow> rw = new RWList<>(poolList);
        rw.setup();
        return rw.get();
    }


    @Override
    public void onRoleOpen() {

    }

    @Override
    public void onRoleEnd() {
        drawTimes = 0;
        historyDrawTimes = 0;
        recordMap.clear();
        freeTimes = 0;
        m1DrawTimes = 0;
    }

    @Override
    public void initSend() {
        noticeUpdate();
    }

    @Override
    public void excelCheck() {

    }

    public void noticeUpdate() {
        role.sendNow(new GoldEggActivityInfoResp(this));
    }

    private GoldEggBaseRow findBaseRow() {
        return role.getGame().table.goldEgg.base.get(configTid());
    }

    private List<GoldEggRewardPoolRow> findPoolList(int group) {
        return role.getGame().table.goldEgg.pool.getPoolListByGroup(group);
    }

    private GoldEggDrawRewardRow findDrawRewardRow(int tid) {
        return role.getGame().table.goldEgg.times.get(tid);
    }

    private List<GoldEggDrawRewardRow> findDrawRewardRows(int group) {
        return role.getGame().table.goldEgg.times.findRowsByGroup(group);
    }
}
